﻿using JGSY.DotNetty.Common;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JGSY.NotNetty.ControllerBus
{
    public class ControllerHelper
    {
        /// <summary>
        /// 控制器类型字典，使用线程安全的ConcurrentDictionary
        /// </summary>
        private readonly ConcurrentDictionary<string, Type> _controllers = new ConcurrentDictionary<string, Type>();

        /// <summary>
        /// 控制器后缀
        /// </summary>
        private const string ControllerSuffix = "Controller";

        /// <summary>
        /// 添加控制器类型
        /// </summary>
        /// <param name="type">控制器类型</param>
        /// <returns>是否添加成功</returns>
        /// <exception cref="DotNettyServerException">当类型为空或不继承自BaseController时抛出</exception>
        public bool TryAddController(Type type)
        {
            // 验证类型不为空
            if (type == null)
                throw new DotNettyServerException("控制器类型不能为null");

            // 验证类型是否继承自BaseController
            if (!typeof(BaseController).IsAssignableFrom(type) || type == typeof(BaseController))
                throw new DotNettyServerException($"控制器类型{type.FullName}必须是{nameof(BaseController)}的非抽象子类");

            // 生成键（移除"Controller"后缀）
            string key = GenerateControllerKey(type.Name);

            // 尝试添加到字典
            return _controllers.TryAdd(key, type);
        }

        /// <summary>
        /// 批量添加控制器类型
        /// </summary>
        /// <param name="types">控制器类型集合</param>
        /// <returns>成功添加的数量</returns>
        public int AddControllers(IEnumerable<Type> types)
        {
            if (types == null)
                throw new ArgumentNullException(nameof(types));

            int addedCount = 0;

            foreach (var type in types)
            {
                if (TryAddController(type))
                    addedCount++;
            }

            return addedCount;
        }

        /// <summary>
        /// 获取控制器类型
        /// </summary>
        /// <param name="key">控制器键</param>
        /// <returns>控制器类型</returns>
        /// <exception cref="DotNettyServerException">当未找到对应控制器时抛出</exception>
        public Type GetController(string key)
        {
            if (string.IsNullOrWhiteSpace(key))
                throw new ArgumentException("控制器键不能为null或空白", nameof(key));

            if (_controllers.TryGetValue(key, out Type type))
            {
                return type;
            }

            throw new DotNettyServerException($"未找到键为'{key}'的控制器");
        }

        /// <summary>
        /// 尝试获取控制器类型
        /// </summary>
        /// <param name="key">控制器键</param>
        /// <param name="type">输出的控制器类型</param>
        /// <returns>是否获取成功</returns>
        public bool TryGetController(string key, out Type type)
        {
            type = null;

            if (string.IsNullOrWhiteSpace(key))
                return false;

            return _controllers.TryGetValue(key, out type);
        }

        /// <summary>
        /// 获取所有控制器类型
        /// </summary>
        /// <returns>控制器类型字典</returns>
        public IReadOnlyDictionary<string, Type> GetAllControllers()
        {
            return _controllers;
        }

        /// <summary>
        /// 生成控制器键（移除"Controller"后缀）
        /// </summary>
        /// <param name="typeName">类型名称</param>
        /// <returns>处理后的控制器键</returns>
        private string GenerateControllerKey(string typeName)
        {
            if (string.IsNullOrWhiteSpace(typeName))
                throw new ArgumentException("类型名称不能为null或空白", nameof(typeName));

            // 如果类型名以"Controller"结尾，则移除该后缀
            if (typeName.EndsWith(ControllerSuffix, StringComparison.OrdinalIgnoreCase))
            {
                return typeName.Substring(0, typeName.Length - ControllerSuffix.Length);
            }

            return typeName;
        }
    }
}
